home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Concept 6
/
CD Concept 06.iso
/
mac
/
UTILITAIRE
/
Little Smalltalk v3.1.4
/
C Source
/
Sources
/
macio.c
< prev
next >
Wrap
Text File
|
1995-01-26
|
10KB
|
417 lines
/*
Little Smalltalk, version 2
Unix specific input and output routines
written by tim budd, January 1988
v3.1.0
------
Converted for use with Macintosh by Julian Barkway,
⌐May 1994, all rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include "env.h"
#include "memory.h"
#include "names.h"
#include "LStResources.h"
#include "macio.h"
#include "memory.proto.h"
#include "fileIn.proto.h"
#include "news.proto.h"
# ifdef TCL
# include "tclprim.proto.h"
# else
# include "winprim.proto.h"
# endif
static long fr(short fnum, char *p, long s);
static void fw(short fnum, char *p, long s);
struct {
int di;
object cl;
short ds;
} dummyObject;
//===========================================================
// Return a full pathname given the directory ID and Vol Ref.
//===========================================================
void getPathName (short volRef, long dirID, char *fullPath)
{
CInfoPBRec catInfo;
Str255 dirName;
OSErr osErr;
fullPath [0] = '\0';
catInfo.dirInfo.ioDrParID = dirID;
catInfo.dirInfo.ioNamePtr = dirName;
do {
catInfo.dirInfo.ioVRefNum = volRef;
catInfo.dirInfo.ioFDirIndex = -1;
catInfo.dirInfo.ioDrDirID = catInfo.dirInfo.ioDrParID;
osErr = PBGetCatInfo (&catInfo, FALSE);
PtoCstr (dirName);
strcat ((char *)dirName, ":");
strcat ((char *)dirName, fullPath);
strcpy (fullPath, (char *)dirName);
} while (catInfo.dirInfo.ioDrDirID != 2);
}
//======================================================
// Return a full pathname given the working directory ID
//======================================================
void getPathNameFromWD (long dirID, char *fullPath)
{
WDPBRec wdInfo;
OSErr osErr;
fullPath [0] = '\0';
wdInfo.ioNamePtr = NULL;
wdInfo.ioVRefNum = (short)dirID;
wdInfo.ioWDIndex = 0;
wdInfo.ioWDProcID = 0;
osErr = PBGetWDInfo (&wdInfo, FALSE);
if (osErr != noErr)
return;
getPathName (wdInfo.ioWDVRefNum, wdInfo.ioWDDirID, fullPath);
}
//=========================================================
// A version of fgets () using Mac, rather than C, file io.
// (Probably better to read in the whole file, then parcel
// lines out as required...)
//=========================================================
char *mac_fgets (char *buf, short n, FILE *fd)
{
short i = 0;
long outCt;
OSErr osErr;
outCt = 1;
osErr = FSRead (fd->fileRef, &outCt, buf + i);
if (osErr != 0)
return NULL;
while ( (buf [i] != '\n')
&& (buf [i] != '\r')
&& (i < n) ) {
i++;
FSRead (fd->fileRef, &outCt, buf + i);
}
if (buf [i] == '\n')
buf [i] = '\r';
buf [i + 1] = '\0';
return buf;
}
//=========================================================
// A version of fputs () using Mac, rather than C, file io.
//=========================================================
int mac_fputs (char *str, FILE *fd)
{
long outCt;
OSErr osErr;
outCt = (long)strlen (str);
osErr = FSWrite (fd->fileRef, &outCt, str);
if (osErr < 0)
return EOF;
return 0;
}
//=======================================================
// imageRead - read in an object image
// we toss out the free lists built initially,
// reconstruct the linkages, then rebuild the free
// lists around the new objects.
// The only objects with nonzero reference counts
// will be those reachable from either symbols
//=======================================================
static long fr (short fnum, char *p, long s)
{
OSErr r;
long ct = s;
r = FSRead (fnum, &ct, p);
if ( r != 0L) {
if (ct != s && r != eofErr)
sysError ("imageRead count error", "");
}
return r;
}
noreturn imageRead (short fnum)
{
short i, size;
object *mBlockAlloc ();
fr (fnum, (char *) &symbols, (long)sizeof(object));
i = 0;
while (fr (fnum, (char *)&dummyObject, (long)sizeof (dummyObject)) != eofErr) {
i = dummyObject.di;
if ((i < 0) || (i > ObjectTableMax))
sysError("reading index out of range","");
objectTable [i].class = dummyObject.cl;
if ( ( objectTable [i].class < 0)
|| ((objectTable [i].class >> 1) > ObjectTableMax) ) {
//****** fprintf ("index %d\n", dummyObject.cl);
sysError ("class out of range", "imageRead");
}
objectTable [i].size = size = dummyObject.ds;
if (size < 0)
size = ((- size) + 1) / 2;
if (size != 0) {
objectTable [i].memory = mBlockAlloc ((int) size);
fr (fnum, (char *) objectTable [i].memory,
sizeof (object) * (int) size);
}
else
objectTable[i].memory = (object *) 0;
}
visit(symbols); /* now restore ref counts, getting rid of unneeded junk */
setFreeLists(); /* toss out the old free lists, build new ones */
}
//=======================================================
// imageWrite - write out an object image
//=======================================================
static void fw (short fnum, char *p, long s)
{
long ct = s;
OSErr r;
r = FSWrite (fnum, &ct, p);
if ( r != 0L
&& ct != s )
sysError ("imageWrite size error", "");
}
void imageWrite (short fnum)
{
short i, size;
fw (fnum, (char *)&symbols, (long)sizeof (object));
for (i = 0; i < ObjectTableMax; i++) {
if (objectTable [i].referenceCount > 0) {
dummyObject.di = i;
dummyObject.cl = objectTable [i].class;
dummyObject.ds = size = objectTable [i].size;
fw (fnum, (char *)&dummyObject, sizeof (dummyObject));
if (size < 0)
size = ((- size) + 1) / 2;
if (size != 0) {
fw (fnum, (char *)objectTable [i].memory,
(long)sizeof (object) * size);
}
}
}
}
#define MAXFILES 20
#define OPEN_READ 1
#define OPEN_WRITE 2
/* we assume this is initialized to NULL */
static FILE fp [MAXFILES];
//===============================================================================
// Following function just returns the file pointer associated with a file number
//===============================================================================
FILE *getFilePointer (short fileNum)
{
return &(fp [fileNum]);
}
//===============================================================================
// Create a file to write to.
//===============================================================================
OSErr createFile (Str255 *fname, short ft)
{
unsigned long fileType, secs;
Str255 tmp;
stFileTypeToMac (ft, fileType);
/* Create temporary file - hopefully with a unique file name! */
/* We'll rename it later... */
PtoCstr ((unsigned char *)fname);
strcat ((char *)fname, "|");
GetDateTime (&secs);
NumToString (secs, tmp);
PtoCstr (tmp);
strcat ((char *)fname, (char *)tmp);
CtoPstr ((char *)fname);
return Create ((unsigned char *)fname, 0, kCreator, fileType);
}
//===============================================================================
// Open a file for reading or writing.
//===============================================================================
OSErr openFile (FILE *fd, char *fname, char *openParms, short ftype)
{
OSErr osErr;
CtoPstr (fname);
fd->openMode = OPEN_READ;
if (openParms [0] == 'w') {
osErr = createFile ((Str255 *)fname, ftype);
if (osErr != 0L) {
fd->openMode = 0;
goto error_exit; /* Create failed */
}
fd->openMode = OPEN_WRITE;
}
osErr = FSOpen ((unsigned char *)fname, 0, &(fd->fileRef));
if (osErr != 0)
fd->openMode = 0;
error_exit:
PtoCstr ((unsigned char *)fname);
return osErr;
}
void closeFile (FILE *fd, char *fname)
{
long fsize;
Str255 tmp;
char *str;
OSErr osErr;
if (fd->fileRef == 0)
return;
FSClose (fd->fileRef);
if (fd->openMode == OPEN_WRITE) {
FlushVol (NULL, 0);
GetEOF (fd->fileRef, &fsize); /* Set file size */
SetEOF (fd->fileRef, fsize);
strcpy ((char *)tmp, fname);
strtok ((char *)tmp, "|"); /* Clip off our unique ID */
CtoPstr (fname);
CtoPstr ((char *)tmp);
osErr = FSDelete (tmp, 0);
if (osErr == 0L || osErr == fnfErr) {
Rename ((unsigned char *)fname, 0,tmp);
PtoCstr ((unsigned char *)fname);
PtoCstr (tmp);
strcpy (fname, (char *)tmp);
}
}
fd->openMode = 0;
fd->fileRef = 0;
}
//=========================================================
// Mac dependent file I/O primitives;
// basically, file numbers are all kept in a large array.
// File operations then just give an index into this array
//=========================================================
object ioPrimitive (int number, object *arguments)
{
short i, j;
char *p, buffer [1024], *openParms;
object returnedObject;
OSErr osErr;
returnedObject = nilobj;
i = intValue (arguments [0]); /* p0 = Smalltalk file number */
switch (number) {
case 0: /* file open: p1 = fname; p2 = open type; p3 = file type */
osErr = openFile (&fp [i],
charPtr (arguments [1]), charPtr (arguments [2]),
intValue (arguments [3]));
if (osErr != 0L)
returnedObject = nilobj; /* Open failed */
else
returnedObject = newInteger (i);
break;
case 1:
closeFile (&fp [i], charPtr (arguments [1]));
break;
case 2: /* file size */
case 3: /* file in */
if (fp [i].fileRef)
fileIn (&fp [i], true);
break;
case 4: /* was Get Character - now Delete File */
p = charPtr (arguments [1]); /* Pathname of file to delete */
CtoPstr (p);
osErr = FSDelete ((unsigned char *)p, 0);
if (osErr == 0L)
returnedObject = falseobj;
else
returnedObject = trueobj; /* returns true if error */
break;
case 5: /* get string */
if (fp [i].fileRef == 0)
break;
j = 0;
buffer [j] = '\0';
while (1) {
if (mac_fgets (&buffer [j], 512, &fp [i]) == NULL)
return nilobj; /* end of file */
j = strlen(buffer)-1;
if (buffer[j] != '\\') // Unix???
break;
/* else we loop again */
}
returnedObject = newStString (buffer);
break;
case 7: /* write an object image */
if (fp [i].fileRef)
imageWrite (fp [i].fileRef);
returnedObject = trueobj;
break;
case 8: /* write a string to a file with no <cr> */
case 9: /* write a string, adding a <cr> */
//****** if (! fp[i])
//****** break;
mac_fputs (charPtr (arguments [1]), &fp [i]);
if (number == 9)
mac_fputs ("\r", &fp [i]);
break;
default:
sysError ("unknown primitive", "filePrimitive");
}
return returnedObject;
}